package com.unibeta.cloudtest.mesher.service.impl;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.unibeta.cloudtest.CloudTestOutput;
import com.unibeta.cloudtest.CloudTestService;
import com.unibeta.cloudtest.config.CloudTestCase;
import com.unibeta.cloudtest.mesher.auth.context.AuthContextHolder;
import com.unibeta.cloudtest.mesher.config.ConfigurationProxy;
import com.unibeta.cloudtest.mesher.dto.CloudTest;
import com.unibeta.cloudtest.mesher.dto.Option;
import com.unibeta.cloudtest.mesher.dto.TreeModel;
import com.unibeta.cloudtest.mesher.service.EditorService;
import com.unibeta.cloudtest.tool.CloudTestReportor;
import com.unibeta.cloudtest.util.CloudTestUtils;
import com.unibeta.cloudtest.util.ObjectDigester;
import com.unibeta.vrules.utils.XmlUtils;

import cn.hutool.core.io.IoUtil;

@Service
public class EditorServiceImpl implements EditorService {

	@Override
	public List<TreeModel> getFileTree(String rootPath) throws Exception {

		List<TreeModel> list = new ArrayList<TreeModel>();

		if (StringUtils.isBlank(rootPath)) {
			return list;
		}

		File[] files = new File(rootPath).listFiles();
		
		if(files == null) {
			return list;
		}

		for (File f : files) {
			if (f.getName().endsWith(".bin")) {
				continue;
			}

			TreeModel node = new TreeModel();
			node.setId(CloudTestUtils.getContextedURI(f.getCanonicalPath()));
			node.setLabel(f.getName());
			node.setLeaf(f.isFile());

			if (f.isFile()) {
				// node.setContent(CloudTestUtils.readFileContent(f.getCanonicalPath()));
			}
			if (f.isDirectory()) {
				node.setChildren(this.getFileTree(f.getCanonicalPath()));
			}
			list.add(node);
		}

		return list;
	}

	@Override
	public void save(String content, String filePath) throws Exception {
		if (new File(filePath).isFile()) {
			XmlUtils.prettyPrint(content, filePath);
		}

	}

	@Override
	public CloudTest load(String filePath) throws Exception {
		CloudTest cloudtest = new CloudTest();
		String content = CloudTestUtils.readFileContent(filePath);
		List<Option> caseList = new ArrayList<Option>();

		try {
			CloudTestCase testcase = ConfigurationProxy.loadCloudTestCase(filePath, null);
			testcase.testCase.stream().forEach(c -> {
				if (!"true".equalsIgnoreCase(c.ignore)) {
					Option op = new Option();
					op.setLabel(c.id);
					op.setValue(c.id);

					caseList.add(op);
				}
			});
			cloudtest.setRunnable(true);
		} catch (Exception e) {
			cloudtest.setRunnable(false);
		}

		cloudtest.setContent(content);
		cloudtest.setCaseList(caseList);

		return cloudtest;
	}

	@Override
	public CloudTest run(CloudTest cloudtest) throws Exception {

		Assert.isTrue(cloudtest != null, "cloudtest request is null");

		CloudTestOutput output = null;

		StringBuffer cases = new StringBuffer();

		if (cloudtest.getCases() != null && cloudtest.getCases().length > 0) {
			Arrays.asList(cloudtest.getCases()).stream().forEach(c -> {
				cases.append(c + ",");
			});
		}

		String caseUri = cloudtest.getCaseUri() + "@[" + cases.toString() + "]";
		if (cloudtest.isReport()) {
			output = CloudTestReportor.report(caseUri, null);
			cloudtest.setReportUrl(ConfigurationProxy.getAPIHost() + "/workspace/"
					+ AuthContextHolder.getContext().getCurrentUserDetails().getUsername()
					+ "-default/reports/default/html/latest.html");
			
		} else {
			output = new CloudTestService().doTest(caseUri);
		}

		cloudtest.setResult(ObjectDigester.toXML(output));

		return cloudtest;
	}

	@Override
	public void newFile(String filePath) throws Exception {

		File file = new File(filePath);
		if (file.exists()) {
			throw new Exception(filePath + " already exists");
		}

		if (!file.isFile()) {
			// throw new Exception(filePath + " is not a valid file name");
		}

		CloudTestUtils.checkFile(filePath);

		file.createNewFile();
	}

	@Override
	public void newFolder(String filePath) throws Exception {
		File file = new File(filePath);

		if (file.exists()) {
			throw new Exception(filePath + " already exists");
		}

		if (!file.isDirectory()) {
			// throw new Exception(filePath + " is not a valid folder name");
		}

		CloudTestUtils.checkFile(filePath);
		file.mkdirs();
	}

	@Override
	public void deleteFile(String filePath) throws Exception {
		CloudTestUtils.deleteFiles(filePath);
		new File(filePath).deleteOnExit();

	}
	
	@Override
	public void restoreWorkspace(String username, String workspace) throws Exception {
		
		if(StringUtils.isBlank(workspace)) {
			workspace = "default";
		}
		
		String cloudtestHome = ConfigurationProxy.getWorkspace() + "/" + username + "-" + workspace + "/";
		CloudTestUtils.deleteFiles(cloudtestHome + "cloudtest");
		CloudTestUtils.checkFile(cloudtestHome + "cloudtest");
		InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("cloudtest.zip");

		File zipFile = new File(cloudtestHome + "cloudtest.zip");
		OutputStream out = new FileOutputStream(zipFile);

		IoUtil.copy(in, out);
		CloudTestUtils.unzipFiles(zipFile);
	}

}
